Lazyflous
·Follow
8 min read·Jun 3, 2023--
Introduction:In this tutorial, we will walk through the step-by-step process of building a full-stack web application using FastAPI as the backend framework and React as the frontend library. FastAPI is a modern, fast (high-performance), web framework for building APIs with Python, while React is a popular JavaScript library for building user interfaces.
We will leverage the power of FastAPI’s simplicity, performance, and auto-generated documentation capabilities to create a robust backend API. For data storage, we will use MongoDB, a flexible and scalable NoSQL database.
On the frontend, we will utilize React’s component-based architecture to create a dynamic and interactive user interface. We will implement features such as user registration, login, and authentication, allowing users to access protected routes.
Throughout this tutorial, we will cover the installation and setup of the necessary tools and dependencies, explain the code structure, and provide detailed explanations of each step involved in building the application. By the end, you will have a solid understanding of how to develop a full-stack web application using FastAPI and React.
So, let’s dive into the exciting world of full-stack web development and start building our application!
Backend: Creating a FastAPI Backend with MongoDBStep 1: Setting up the Backend Environment1. Install Python: Make sure you have Python installed on your system. You can download and install Python from the official website: python.org
2. Install FastAPI: FastAPI is a modern, fast (high-performance), web framework for building APIs with Python. Open a terminal or command prompt and run the following command:
pip install fastapi3. Install PyMongo: PyMongo is the official MongoDB driver for Python. It allows you to interact with the MongoDB database. Run the following command:
pip install pymongo4. Install PyJWT: PyJWT is a Python library to work with JSON Web Tokens (JWT). It helps in generating and verifying tokens for authentication. Run the following command:
pip install PyJWTStep 2: Creating the Backend Application1. Create a new file called `main.py` and open it in a code editor.
2. Import the required modules and libraries:
from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel from pymongo import MongoClient import jwt from jwt import encode as jwt_encode from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from fastapi import Depends, HTTPException from bson import ObjectId3. Initialize the FastAPI app:
app = FastAPI()4. Set up the CORS (Cross-Origin Resource Sharing) middleware to allow requests from your frontend. Replace `http://localhost:3000` with the actual origin of your frontend application:
app.add_middleware( CORSMiddleware, allow_origins=["http://localhost:3000"], # Add your frontend origin here allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )5. Define a `User` model using Pydantic:
class User(BaseModel): username: str = None # Make the username field optional email: str password: str6. Connect to the MongoDB database:
# MongoDB connection client = MongoClient("mongodb://localhost:27017") db = client["mydatabase"] users_collection = db["users"]7. Define the security scheme for JWT authentication:
# Secret key for signing the token SECRET_KEY = "your-secret-key-goes-here"security = HTTPBearer()8. Create the homepage route:
@app.get("/") def homepage(): return {"message": "Welcome to the homepage"}9. Implement the login route:
@app.post("/login") def login(user: User): # Check if user exists in the database user_data = users_collection.find_one( {"email": user.email, "password": user.password} ) if user_data: # Generate a token token = generate_token(user.email) # Convert ObjectId to string user_data["_id"] = str(user_data["_id"]) # Store user details and token in local storage user_data["token"] = token return user_datareturn {"message": "Invalid email or password"}10. Implement the registration route:
@app.post("/register") def register(user: User): # Check if user already exists in the database existing_user = users_collection.find_one({"email": user.email}) if existing_user: return {"message": "User already exists"}# Insert the new user into the database user_dict = user.dict() users_collection.insert_one(user_dict) # Generate a token token = generate_token(user.email) # Convert ObjectId to string user_dict["_id"] = str(user_dict["_id"]) # Store user details and token in local storage user_dict["token"] = token return user_dict11. Implement the `/api/user` route to fetch user data based on the JWT token:
@app.get("/api/user") def get_user(credentials: HTTPAuthorizationCredentials = Depends(security)): # Extract the token from the Authorization header token = credentials.credentials# Authenticate and retrieve the user data from the database based on the token # Here, you would implement the authentication logic and fetch user details # based on the token from the database or any other authentication mechanism# For demonstration purposes, assuming the user data is stored in local storage # Note: Local storage is not accessible from server-side code # This is just a placeholder to demonstrate the concept user_data = { "username": "John Doe", "email": "johndoe@example.com" }if user_data["username"] and user_data["email"]: return user_dataraise HTTPException(status_code=401, detail="Invalid token")12. Define a helper function to generate a JWT token:
def generate_token(email: str) -> str: payload = {"email": email} token = jwt_encode(payload, SECRET_KEY, algorithm="HS256") return token13. Start the FastAPI server:
if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)Step 3: Running the Backend Application1. Open a terminal or command prompt and navigate to the directory where `main.py` is located.
2. Run the following command to start the backend server:
uvicorn main:app - reloadThe backend server will start running on `http://localhost:8000`.
Congratulations! You have created the backend of your application using FastAPI and MongoDB. You now have routes for homepage, login, registration, and retrieving user data.
Next, let’s move on to the frontend and create the necessary React components.
Frontend: Building the React ApplicationStep 1: Setting up the Frontend Environment1. Install Node.js: Ensure that you have Node.js installed on your system. You can download and install it from the official website: nodejs.org
2. Install Yarn: Yarn is a package manager for Node.js and is an alternative to npm. Open a terminal or command prompt and run the following command to install Yarn globally:
npm install -g yarnStep 2: Creating the Frontend Application1. Create a new directory for your frontend application and navigate to it using a terminal or command prompt.
2. Initialize a new React project by running the following command:
yarn create react-app my-appThis command creates a new directory named `my-app` with a basic React project structure.
3. Navigate to the project directory:
cd my-app4. Install additional dependencies required for the frontend application:
yarn add react-router-dom axios- `react-router-dom`: A routing library for React that allows you to handle different routes in your application. — `axios`: A library for making HTTP requests from the frontend.
Step 3: Implementing the Frontend ComponentsReplace the contents of the `src/App.js` file with the following code:import React from 'react'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import Login from './components/Login'; import Register from './components/Register'; import Homepage from './components/Homepage'; import Navbar from './components/Navbar'; import './styles.css'; // Import the styles.css filefunction App() { return (); }export default App;This code sets up the main application component and configures the routes using `react-router-dom`.
2. Create a new directory named `src/components`.
3. Create a new file `src/components/Homepage.js` and add the following code:
import React, { useEffect, useState } from 'react';function Homepage() { const [userData, setUserData] = useState(null);useEffect(() => { // Fetch user data from the API endpoint fetch('http://localhost:8000/api/user', { headers: { Authorization: `Bearer ${localStorage.getItem('token')}`, }, }) .then(response => response.json()) .then(data => setUserData(data)) .catch(error => console.error(error)); }, []);const username = localStorage.getItem('username'); const email = localStorage.getItem('email');return ( Welcome to the Homepage {userData && (Welcome {username}, {email} to the homepage!
)} ); }export default Homepage;This component fetches the user data from the backend API and displays a welcome message on the homepage.
4. Create a new file `src/components/Login.js` and add the following code:
import React from 'react'; import { useState } from 'react'; import axios from 'axios'; import { useNavigate } from 'react-router-dom';function Login() { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [message, setMessage] = useState(''); const navigate = useNavigate();const handleLogin = () => { // Send login request to the backend axios .post('http://localhost:8000/login', { email, password }) .then(response => { setMessage(response.data.message); const { username, email, token } = response.data; localStorage.setItem('username', username); localStorage.setItem('email', email); localStorage.setItem('token', token);// Redirect to homepage using navigate navigate('/'); // Replace '/' with the homepage URL if needed }) .catch(error =>{ console.error(error); setMessage('Error logging in. Please try again.'); }); };return ( LoginsetEmail(e.target.value)} /> setPassword(e.target.value)} /> Login {message &&{message}
}); }export default Login;This component provides a login form that sends a login request to the backend API.
5. Create a new file `src/components/Register.js` and add the following code:
import React, { useState } from 'react'; import axios from 'axios'; import { useNavigate } from 'react-router-dom';function Register() { const [username, setUsername] = useState(''); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [message, setMessage] = useState(''); const navigate = useNavigate();const handleRegister = () => { // Send registration request to the backend axios .post('http://localhost:8000/register', { username, email, password }) .then(response => { setMessage(response.data.message); const { username, email, token } = response.data; localStorage.setItem('username', username); localStorage.setItem('email', email); localStorage.setItem('token', token);// Redirect to homepage using navigate navigate('/'); // Replace '/' with the homepage URL if needed }) .catch(error => { console.error(error); setMessage('Error registering. Please try again.'); }); };return ( RegistersetUsername(e.target.value)} /> setEmail(e.target.value)} /> setPassword(e.target.value)} /> Register {message &&{message}
}); }export default Register;This component provides a registration form that sends a registration request to the backend API.
6. Create a new file `src/components/Navbar.js` and add the following code:
import React from 'react'; import { Link } from 'react-router-dom';function Navbar() { return (HomeLoginRegister); }export default Navbar;This component provides a basic navigation bar with links to the homepage, login, and registration pages.
Step 4: Running the Frontend Application1. Open a terminal or command prompt and navigate to the directory of your frontend application (`my-app`).
2. Run the following
command to start the React development server:
yarn startThe frontend server will start running on `http://localhost:3000`.
3. Open your web browser and visit `http://localhost:3000` to see the application in action.
Congratulations on completing the tutorial on building a full-stack web application with FastAPI and React! We have covered a wide range of concepts and technologies, from setting up the backend using FastAPI and MongoDB to creating a dynamic user interface with React.
Conclusion:Throughout the tutorial, we have learned how to create API endpoints for user registration, login, and authentication using FastAPI. We have also explored how to store user data in a MongoDB database and implement token-based authentication using JSON Web Tokens (JWT).
On the frontend side, we have built a React application with multiple routes, including a homepage, login, and registration pages. We have used React hooks, such as useState and useEffect, to manage component state and handle API requests. We have also implemented protected routes that require authentication to access.
By combining FastAPI’s efficient backend capabilities with React’s flexible and interactive frontend components, we have created a complete web application that provides a seamless user experience.
With the knowledge gained from this tutorial, you can further enhance the application by adding more features, implementing additional API endpoints, or customizing the frontend design according to your specific requirements.
Remember to explore the official documentation of FastAPI and React for more in-depth knowledge and to stay updated with the latest features and best practices.
Building full-stack web applications allows you to create powerful and dynamic solutions that can cater to a wide range of use cases. You now have a strong foundation to continue exploring and expanding your skills in web development.
Keep learning, practicing, and exploring new technologies to unlock endless possibilities in the world of full-stack web development!